package com.kexio.core.data.domain;

import java.util.List;

import com.baomidou.mybatisplus.annotation.TableField;
import com.fasterxml.jackson.annotation.JsonInclude;

import lombok.Data;
import lombok.EqualsAndHashCode;

/**
 * 树形节点基类
 * 
 * 在AuditEntity基础上增加树形结构字段：
 * - parentId: 父节点ID
 * - level: 节点层级
 * - sort: 排序号
 * - path: 节点路径
 * - children: 子节点列表
 * 
 * 适用于部门、菜单、分类等树形结构数据
 * 
 * @author Kexio
 * @since 1.0.0
 */
@Data
@EqualsAndHashCode(callSuper = true)
public abstract class TreeNode<T extends TreeNode<T>> extends AuditEntity {

    /**
     * 父节点ID (根节点为0)
     */
    private Long parentId;

    /**
     * 节点层级 (从1开始)
     */
    private Integer level;

    /**
     * 排序号
     */
    private Integer sort;

    /**
     * 节点路径 (从根到当前节点的ID路径，如: /1/2/3/)
     */
    private String path;

    /**
     * 子节点列表 (查询时填充，不存储在数据库)
     */
    @TableField(exist = false)
    @JsonInclude(JsonInclude.Include.NON_EMPTY)
    private List<T> children;

    /**
     * 是否为叶子节点
     */
    @TableField(exist = false)
    private Boolean isLeaf;

    /**
     * 判断是否为根节点
     */
    public boolean isRoot() {
        return parentId == null || parentId == 0L;
    }

    /**
     * 判断是否有子节点
     */
    public boolean hasChildren() {
        return children != null && !children.isEmpty();
    }

    /**
     * 获取子节点数量
     */
    public int getChildrenCount() {
        return children == null ? 0 : children.size();
    }

    /**
     * 添加子节点
     */
    public void addChild(T child) {
        if (children == null) {
            children = new java.util.ArrayList<>();
        }
        children.add(child);
    }

    /**
     * 生成节点路径
     */
    public void generatePath() {
        if (isRoot()) {
            this.path = "/" + getId() + "/";
        } else {
            // 路径需要根据父节点路径生成，通常在Service层处理
            this.path = "/" + getId() + "/";
        }
    }
}
